package main

import (
	"compress/gzip"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

type Response struct {
	Code int         `json:"code"`
	Show int         `json:"show"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data"` // 使用 interface{} 来处理可能为对象或数组的情况
}

type ArticleData struct {
	ID          int     `json:"id"`
	CID         int     `json:"cid"`
	Title       string  `json:"title"`
	Content     string  `json:"content"`
	DeleteTime  *string `json:"delete_time"`
	URL         *string `json:"url"`
	AppID       string  `json:"appid"`
	UserID      int     `json:"user_id"`
	AppName     string  `json:"appname"`
	Status      int     `json:"status"`
	Sort        int     `json:"sort"`
	Cover       string  `json:"cover"`
	JoinTime    int     `json:"join_time"`
	CreateTime  string  `json:"create_time"`
	UpdateTime  string  `json:"update_time"`
	PublishTime *string `json:"publish_time"`
}

var startID = 5631

func main() {
	downloadMain()
}

func downloadMain() {
	for {
		url := "https://wenzhang.ihuaimi.com/api/article/detail?id=" + strconv.Itoa(startID)
		fmt.Println("Fetching article with ID:", startID)

		resp, err := fetchArticle(url)
		if err != nil {
			fmt.Println("Error fetching article:", err)
			return
		}

		// 根据 code 判断是否继续
		switch resp.Code {
		case 1:
			// 尝试将 data 转换为 ArticleData
			if articleData, ok := parseArticleData(resp.Data); ok {
				saveContent(articleData)
			} else {
				fmt.Println("Error: Unexpected data format for article with ID:", startID)
			}
		case 2:
			fmt.Println("Terminating due to code 2 response.")
			return
		default:
			fmt.Println("Skipping due to non-collectable code:", resp.Code)
		}
		time.Sleep(3*time.Second)
		startID++


	}
}

func fetchArticle(url string) (*Response, error) {
	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}

	// 设置请求头
	req.Header.Set("Accept", "application/json, text/plain, */*")
	req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9")
	req.Header.Set("Connection", "keep-alive")
	req.Header.Set("Host", "wenzhang.ihuaimi.com")
	req.Header.Set("Referer", "https://wenzhang.ihuaimi.com/pc/sate/unsel?cid=9")
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36")
	req.Header.Set("sec-ch-ua", "\"Not)A;Brand\";v=\"99\", \"Google Chrome\";v=\"127\", \"Chromium\";v=\"127\"")
	req.Header.Set("sec-ch-ua-mobile", "?0")
	req.Header.Set("sec-ch-ua-platform", "\"Windows\"")
	req.Header.Set("token", "5ceddae33bf629d55050bba22607fb41")
	req.Header.Set("version", "1.9.0")

	// 发起请求
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	// 检查是否需要解压响应
	var reader io.Reader
	if resp.Header.Get("Content-Encoding") == "gzip" {
		reader, err = gzip.NewReader(resp.Body)
		if err != nil {
			return nil, err
		}
		defer reader.(*gzip.Reader).Close()
	} else {
		reader = resp.Body
	}

	// 读取响应内容
	body, err := ioutil.ReadAll(reader)
	if err != nil {
		return nil, err
	}

	// 解析 JSON 响应
	var response Response
	err = json.Unmarshal(body, &response)
	if err != nil {
		return nil, err
	}

	return &response, nil
}

func parseArticleData(data interface{}) (*ArticleData, bool) {
	// 将 data 转换为 map 以便进一步解析
	dataMap, ok := data.(map[string]interface{})
	if !ok {
		return nil, false
	}

	// 将 map 重新解析为 ArticleData 结构体
	var articleData ArticleData
	dataBytes, err := json.Marshal(dataMap)
	if err != nil {
		return nil, false
	}

	err = json.Unmarshal(dataBytes, &articleData)
	if err != nil {
		return nil, false
	}

	return &articleData, true
}

func saveContent(data *ArticleData) {
	// 创建 CID 目录
	cidDir := strconv.Itoa(data.CID)
	err := os.MkdirAll(cidDir, os.ModePerm)
	if err != nil {
		fmt.Println("Error creating directory:", err)
		return
	}

	// 清理并生成文件名
	title := sanitizeFileName(data.Title)
	filePath := filepath.Join(cidDir, title+".txt")

	// 写入内容
	err = ioutil.WriteFile(filePath, []byte(data.Content), 0644)
	if err != nil {
		fmt.Println("Error writing file:", err)
		return
	}

	fmt.Println("Article saved:", filePath)
}

// 清理文件名中的非法字符
func sanitizeFileName(name string) string {
	invalidChars := []string{"\\", "/", ":", "*", "?", "\"", "<", ">", "|"}
	for _, char := range invalidChars {
		name = strings.ReplaceAll(name, char, "_")
	}
	return name
}
